package components.plugins.effects {
	import UIUtils.uif_util;
	import UIUtils.uif_utilBitmap;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BitmapDataChannel;
	import flash.display.Shape;
	import flash.filters.BlurFilter;
	import flash.filters.ColorMatrixFilter;
	import flash.filters.DisplacementMapFilter;
	import flash.filters.DisplacementMapFilterMode;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;

	public class clte_drawing extends clte_emboss {
		private var _grayFilter: ColorMatrixFilter;
		public static const COUNTERMATRIX: Array = [0,20,0,
													20,-80,20,
													0,20,0];
		
		
		public function clte_drawing(a_params:Object) {
			super(uif_util.union({
				matrix		: COUNTERMATRIX,
				divisor		: 5,
				lineWeight	: 1,
				sourceBlur	: 2,
				drawingBlur	: 1,
				stroke		: 0,
				strokeDensity 	: 0,
				strokeSize		: 0.1,
				strokeWeight	: 2
			}, a_params));
				
			_grayFilter = new ColorMatrixFilter();
		}
		
		protected function drawingBMD(source: BitmapData): BitmapData {
			var np		: Point = new Point();
			var a_tmp	: BitmapData = new BitmapData(source.width, source.height, true, 0);
			var black	: BitmapData = new BitmapData(source.width, source.height, true, 0xFF000000);
			a_tmp.applyFilter(source, source.rect, np, _filter);
			if (params.drawingBlur > 1)
				a_tmp.applyFilter(a_tmp, a_tmp.rect, np, new BlurFilter(params.drawingBlur, params.drawingBlur, 2));
			a_tmp.applyFilter(a_tmp, a_tmp.rect, np, _grayFilter);
			black.copyChannel(a_tmp, a_tmp.rect, np, BitmapDataChannel.BLUE, BitmapDataChannel.ALPHA);
			return black;
		}
		
		protected function strokeFilter2(bmd: BitmapData, orientation: int=0, density: int=2000, size: Number=0.1, weight:int=1): void {
			var np			: Point = new Point();
			var lines		: BitmapData = copyBD(bmd);
			var stamp		: Shape = new Shape();
			var sizeInt		: int = Math.max(bmd.width, bmd.height) * size;
			var sizeInt2	: int = sizeInt / 2;
			
			stamp.graphics.lineStyle(weight, 0xFF0000);
			
			if (orientation == 0) {
				stamp.graphics.moveTo(sizeInt, 0);
				stamp.graphics.lineTo(0, sizeInt);
			} else if (orientation == 1) {
				stamp.graphics.moveTo(0, 0);
				stamp.graphics.lineTo(sizeInt, sizeInt);
			} else if (orientation == 2) {
				stamp.graphics.moveTo(sizeInt2, 0);
				stamp.graphics.lineTo(sizeInt2, sizeInt);
			} else if (orientation == 3) {
				stamp.graphics.moveTo(0, sizeInt2);
				stamp.graphics.lineTo(sizeInt, sizeInt2);
			} 
			
			var ct: ColorTransform = new ColorTransform();
			lines.fillRect(lines.rect, 0xFF000000);
			for (var i:int=0; i<density; i++) {
				var mat: Matrix = new Matrix();
				mat.translate(-sizeInt2 + Math.random() * bmd.width, -sizeInt2 + Math.random() * bmd.height);
				ct.alphaMultiplier = Math.random();
				lines.draw(stamp, mat, ct);
			}
			
			var filter: DisplacementMapFilter = new DisplacementMapFilter(lines, np, 
				BitmapDataChannel.RED, BitmapDataChannel.RED, 3, 3, DisplacementMapFilterMode.CLAMP, 0);
			
			bmd.applyFilter(bmd, bmd.rect, np, filter);
			//bmd.draw(lines);
		}
		
		
		override public function execute(bitmapData: BitmapData):void {
			var np		: Point = new Point();
			
			_grayFilter.matrix = [
				0.3 * params.lineWeight, 0.6 * params.lineWeight, 0.1 * params.lineWeight, 0.0, 0.0,
				0.3 * params.lineWeight, 0.6 * params.lineWeight, 0.1 * params.lineWeight, 0.0, 0.0,
				0.3 * params.lineWeight, 0.6 * params.lineWeight, 0.1 * params.lineWeight, 0.0, 0.0,
				0.0, 0.0, 0.0, 1.0 * params.lineWeight, 0.0
			];

			var a_tmp	: BitmapData = drawingBMD(bitmapData);
			var ct		: ColorTransform;
			var invert	: ColorTransform = new ColorTransform(-1, -1, -1, params.alpha, 0xFF, 0xFF, 0xFF)
			
			if (params.invert) ct = new ColorTransform(-1, -1, -1, params.alpha, 0xFF + params.colorOffset, 0xFF + params.colorOffset, 0xFF + params.colorOffset);
			else ct = new ColorTransform(1, 1, 1, params.alpha, params.colorOffset, params.colorOffset, params.colorOffset );
			
//			bitmapData.fillRect(bitmapData.rect, 0xFFFF0000);
			if (params.sourceBlur > 1) 
				bitmapData.applyFilter(bitmapData, bitmapData.rect, np, new BlurFilter(params.sourceBlur, params.sourceBlur, 2));
			if (params.strokeDensity)
				strokeFilter2(bitmapData, params.stroke, params.strokeDensity, params.strokeSize, params.strokeWeight);
			bitmapData.draw(a_tmp, null, ct, blendMode);
			a_tmp.dispose();
		}
		
		override public function incValue1():void {
			params.alpha = changeValue(params.alpha, 0.1, 1);
		}
		
		override public function incValue2():void {
			params.sourceBlur = changeValue(params.sourceBlur, 1, 10);
		}
		
		override public function incValue3():void {
			params.lineWeight = changeValue(params.lineWeight, 1, 10);
		}
		
		override protected function getParamName():Array {
			return [
				locale.ALPHA,
				locale.BLUR,
				locale.WEIGHT,
				locale.BLENDMODE
			];
		}
		
		override protected function getValues():Array {
			return [
				params.alpha * 100,
				params.sourceBlur * 10,
				params.lineWeight * 10
			];
		}
		
		override protected function setValues(a_set:Array):void {
			params.alpha  		= a_set[0] * .01;
			params.sourceBlur  	= a_set[1] * .1;
			params.lineWeight  	= a_set[2] * .1;
			super.setValues(a_set);
		}
	}
}